package model.AI;

import java.awt.Color;
import java.util.Collections;
import java.util.List;

import javax.swing.ImageIcon;

import control.networking.RiskAIClient;

import model.CardType;
import model.Map;
import model.Player;
import model.Territory;
import model.TradeCard;
import model.Map.GamePhase;

/**
 * The Simple implementation of the Cyborg interface.
 * 
 * @author David Shefchik
 * 
 */
public class SimpleCyborg extends Player implements Cyborg {

	private int age = 4000;
	private String location = "EARTH";
	private List<model.Territory> myTerritories;
	private boolean gameHasStarted;
	private RiskAIClient client;

	// public SimpleCyborg(String name, Color color, ImageIcon icon, Map map)
	public SimpleCyborg(String name, Color color, ImageIcon icon) {
		super(name, color, icon);

		this.setDiceAttack(3);
		this.setDiceDefend(2);
		age = 2500;
		location = "Earth";
		gameHasStarted = false;
	}

	public synchronized void cardPhase() {
		System.out.println("Cards: " + this.getNumCards());
		if (this.getNumCards() >= 3) {
			List<model.TradeCard.Choice> tradeList = TradeCard.tradeList(this);
			if (!tradeList.isEmpty()) {
				model.Card card1 = tradeList.get(0).getCard1();
				model.Card card2 = tradeList.get(0).getCard2();
				model.Card card3 = tradeList.get(0).getCard3();
				TradeCard.tradeCard(this, card1, card2, card3);
				setChanged();
				this.notifyObservers("NewMap");
				try {
					synchronized(this){
						this.wait(500);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}

	public void placePhase() {

		this.updateTerritories();

		Collections.shuffle(myTerritories);
		for (int i = 0; i < myTerritories.size(); i++) {
			if (MapInfo
					.hasBorderingEnemyTerritories(this, myTerritories.get(i))) {
				if (troopsToAdd > 0) {
					myTerritories.get(i).addTroop(troopsToAdd);
					this.removeBonus(troopsToAdd);
					System.out.println("AI UPDATE MAP PLACE PHASE");
					this.setChanged();
					this.notifyObservers("NewMap");
					System.out.println("AI called notifyObservers");
					try {
						synchronized(this){
							this.wait(500);
							
						}
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					break;
				}

			}
		}

	}

	private void selectTerritories() {

		List<Territory> list = MapInfo.listUnownedTerritories(this);
		Collections.shuffle(list);
		Territory toAddTo = list.get(0);
		toAddTo.addTroop(1);
		toAddTo.setRuler(this);
		this.removeBonus(1);

	}

	public void attackPhase() {
		this.updateTerritories();
		for (int i = 0; i < myTerritories.size(); i++) {
			this.updateTerritories();
			if (!MapInfo.getEnemyBorderingTerritories(myTerritories.get(i))
					.isEmpty())
				if (myTerritories.get(i).getTroopNumber() > (MapInfo
						.getWeakestBorderingEnemyTerritory(myTerritories.get(i))
						.getTroopNumber() / 2)) {

					new model.Combat(myTerritories.get(i), MapInfo
							.getWeakestBorderingEnemyTerritory(myTerritories
									.get(i)));
					setChanged();
					this.notifyObservers("NewMap");
					try {
						synchronized(this){
							this.wait(500);
						}
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

		}
		if (this.isCardEligible() && !this.getMap().getMapCards().isEmpty()) {
			this.getMap().giveCard(this);
			this.setCardEligible(false);
			setChanged();
			this.notifyObservers("NewMap");
		}
	}

	public void movePhase() {
		boolean moved = false;
		this.updateTerritories();
		for (Territory temp : myTerritories) {
			if (temp.getTroopNumber() > 1
					&& !MapInfo.hasBorderingEnemyTerritories(this, temp)) {
				for (Territory dest : temp.listNeighbors()) {
					if (MapInfo.hasBorderingEnemyTerritories(this, dest)) {
						if (!moved) {
							new model.Movement(temp, dest, temp
									.getTroopNumber() - 1);
							moved = true;
							setChanged();
							this.notifyObservers("NewMap");
							try {
								synchronized(this){
									this.wait(500);
								}
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
				}
			}
		}

	}

	public void talkTrash() {
		// TALK TRASH VIA CHAT TO OTHER PLAYERS

	}

	private synchronized void updateTerritories() {
		myTerritories = MapInfo.getPlayersTerritories(this);

	}

	@Override
	public void run() {
		System.out.println("\n SIMPLE AI: " + this.getName() + " RUNNING ");
		if (this.getMap().getPhase() == GamePhase.PLAYING) {
			this.setCardEligible(false);
			gameHasStarted = true;
			MapInfo.calculateTurnBonus(this);
			cardPhase();
			placePhase();
			attackPhase();
			movePhase();
			talkTrash();
		} else if (this.getMap().getPhase() == GamePhase.SELECTING) {
			this.troopsToAdd = 1;
			selectTerritories();
			if (MapInfo.listUnownedTerritories(this).isEmpty()) {
				this.getMap().setPhase(GamePhase.PLACING);
			}
			setChanged();
			this.notifyObservers("NewMap");
		} else {
			this.troopsToAdd = 1;
			System.out.println("AI add 1");
			placePhase();
			System.out.println("AI ADDED 1");

			if (this.getBonus() == 0) {
				this.getMap().setPhase(GamePhase.PLAYING);
			}
			
			setChanged();
			this.notifyObservers("NewMap");
			System.out.println("AI Updated Map");
		}
		
		System.out.println("end AI turn");
		setChanged();
		this.notifyObservers("EndTurn");
		
	}

}
